/**
 * @Author: zhongyang
 * @Date: 2022/6/22 14:28
 */

package main

import "fmt"

/**
02_工厂方法模式
概念：工厂方法模式，又称工厂模式、多态工厂模式和虚拟构造器模式，通过定义工厂父类负责定义创建对象的公共接口，而子类则负责生成具体的对象。
作用：将类的实例化（具体产品的创建）延迟到工厂类的子类（具体工厂）中完成，即由子类来决定应该实例化（创建）哪一个类。
该模式完善了简单工厂的缺陷

练习：可自己实现乘法和除法工厂
*/

// =============== 工厂模式 ================

// ================ 1.创建抽象产品 ================

// Operator 是被封装的实际类接口
type Operator interface {
	SetA(int)
	SetB(int)
	Result() int
}

// ================ 2.创建抽象工厂 ================
// OperatorFactory 工厂接口
type OperatorFactory interface {
	Create() Operator
}

// ================ 3.实现具体产品 ================
type OperatorBase struct {
	a, b int
}

// SetA 设置A
func (o *OperatorBase) SetA(i int) {
	o.a = i
}

// SetB 设置B
func (o *OperatorBase) SetB(i int) {
	o.b = i
}

type PlusOperator struct {
	*OperatorBase
}

func (receiver PlusOperator) Result() int {
	return receiver.a + receiver.b
}

type MinusOperator struct {
	*OperatorBase
}

func (m MinusOperator) Result() int {
	return m.a - m.b
}

// ================ 4.实现具体工厂 ================
type PlusOperatorFactory struct {
}

func (receiver PlusOperatorFactory) Create() Operator {
	return &PlusOperator{OperatorBase: &OperatorBase{}}
}

type MinusOperatorFactory struct {
}

func (m MinusOperatorFactory) Create() Operator {
	return MinusOperator{OperatorBase: &OperatorBase{}}
}

type MclOperatorFactory struct {
}

func main() {
	// 首先创建一个加法工厂
	plusFactory := &PlusOperatorFactory{}
	fmt.Println(compute(plusFactory, 1, 2))
	// 创建除法工厂
	minusFactory := &MinusOperatorFactory{}
	fmt.Println(compute(minusFactory, 2, 3))
}

func compute(factory OperatorFactory, a, b int) int {
	operator := factory.Create()
	operator.SetA(a)
	operator.SetB(b)
	return operator.Result()
}
